package java.util.stream.lock;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;

/**
 * 自旋锁 实现
 *
 * @author fangjiaxiaobai@gmail.com
 * @date 2020-05-13
 * @since 1.0.0
 */
public class spinLockDemo {

    public static void main(String[] args) {

        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 15, 2000L, TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue<>(10), new ThreadFactory() {
            private final AtomicInteger mThreadNum = new AtomicInteger(1);

            @Override
            public Thread newThread(Runnable r) {
                Thread t = new Thread(r, "t-" + mThreadNum.getAndIncrement());
                System.out.println(t.getName() + "has been created");
                return t;
            }
        });

        // 预先启动所有线程
        threadPoolExecutor.prestartAllCoreThreads();

        SpinLock spinLock = new SpinLock();

        for (int i = 0; i < 10; i++) {
            threadPoolExecutor.execute(() -> {
                spinLock.lock();
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                spinLock.unlock();
            });
        }

        threadPoolExecutor.shutdown();

    }


}

class SpinLock {

    AtomicReference<Thread> atomicReference = new AtomicReference<>();

    public void lock() {

        Thread thread = Thread.currentThread();

        while (!atomicReference.compareAndSet(null, thread)) {

        }
        System.out.println(String.format("[%s] 进入，获取到锁", thread.getName()));
    }


    public void unlock() {
        Thread thread = Thread.currentThread();

        atomicReference.compareAndSet(thread, null);
        System.out.println(String.format("[%s] 离开，释放", thread.getName()));
    }

}
